package com.party.admin.biz.mall;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Function;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.party.admin.biz.distribution.DistributionBizService;
import com.party.admin.biz.file.FileBizService;
import com.party.admin.utils.RealmUtils;
import com.party.admin.web.dto.input.mall.MallGoodsInput;
import com.party.admin.web.dto.output.mall.MallGoodsOutput;
import com.party.common.paging.Page;
import com.party.common.utils.DateUtils;
import com.party.common.utils.LangUtils;
import com.party.common.utils.StringUtils;
import com.party.core.exception.BusinessException;
import com.party.core.model.mall.*;
import com.party.core.service.cos.CosBizService;
import com.party.core.service.mall.*;
import com.party.core.service.mall.biz.GoodsCategoryBizService;
import com.party.core.service.mall.biz.GoodsDetailBizService;
import com.party.core.service.mall.biz.GoodsResourceBizService;
import com.party.core.service.mall.biz.ProductBizService;
import com.party.core.utils.MyBeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 商城商品业务接口
 * Created by wei.li
 *
 * @date 2017/8/16 0016
 * @time 11:06
 */
@Service
public class MallGoodsBizService {

    @Autowired
    private IMallGoodsService mallGoodsService;
    @Autowired
    private FileBizService fileBizService;
    @Autowired
    private CosBizService cosBizService;
    @Autowired
    private ProductBizService productBizService;
    @Autowired
    private GoodsResourceBizService goodsResourceBizService;
    @Autowired
    private GoodsDetailBizService goodsDetailBizService;
    @Autowired
    private GoodsCategoryBizService goodsCategoryBizService;
    @Autowired
    private IMallGoodsResourcesService mallGoodsResourcesService;
    @Autowired
    private IMallCategoryService mallCategoryService;
    @Autowired
    private IMallOrderDetailService mallOrderDetailService;
    @Autowired
    private IMallShoppingCartService mallShoppingCartService;
    @Autowired
    private IMallProductService mallProductService;
    @Autowired
    private MallBrandBizService mallBrandBizService;
    @Autowired
    private IMallGoodsFavoriteService mallGoodsFavoriteService;
    @Autowired
    private IMallStoreResourcesService mallStoreResourcesService;
    @Autowired
    private IMallGoodsCategoryService mallGoodsCategoryService;
    @Autowired
    private MallShowGoodsBizService mallShowGoodsBizService;
    @Autowired
    private DistributionBizService distributionBizService;

    @Value("#{party['shop.url.protocol']}")
    private String shopUrl;

    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 商城商品列表
     *
     * @param goods  商品信息
     * @param params 查询参数
     * @param page   分页参数
     * @return 商城商品
     */
    public List<MallGoodsOutput> list(MallGoods goods, Map<String, Object> params, Page page) {
        Integer status = goods.getStatus();
        if (goods.getStatus() != null && goods.getStatus().equals(4)) {
            params.put("openStartTime", new Date());
            goods.setStatus(MallGoods.STATUS_UP);
        }
        List<MallGoodsWithAuthor> list = mallGoodsService.withAuthorListPage(goods, params, page);
        goods.setStatus(status);
        List<MallGoodsOutput> mallGoodsOutputList
                = LangUtils.transform(list, new Function<MallGoodsWithAuthor, MallGoodsOutput>() {
            @Override
            public MallGoodsOutput apply(MallGoodsWithAuthor mallGoodsWithAuthor) {
                MallGoodsOutput mallGoodsOutput = MallGoodsOutput.transform(mallGoodsWithAuthor);
                String filePath = fileBizService.getUploadCIPath(mallGoodsWithAuthor.getMemberId(), "mallGoods");
                String qrCodeUrl = cosBizService.getPreviewPictureUrl(filePath + mallGoodsWithAuthor.getId());
                mallGoodsOutput.setQrCodeUrl(qrCodeUrl);
                return mallGoodsOutput;
            }
        });
        return mallGoodsOutputList;
    }

    /**
     * 商品保存
     *
     * @param mallGoods   商品信息
     * @param goodsDetail 详情
     * @return
     * @throws Exception
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public String saveGoodsBiz(MallGoodsInput mallGoods, MallGoodsDetail goodsDetail) throws Exception {
        String memberId = RealmUtils.getCurrentUser().getId();
        if (mallGoods.getOpenStatus() != null) {
            if (mallGoods.getOpenStatus().equals(1) || mallGoods.getOpenStatus().equals(2)) {
                mallGoods.setStatus(MallGoods.STATUS_UP); // 上架
            } else if (mallGoods.getOpenStatus().equals(3)) {
                mallGoods.setStatus(MallGoods.STATUS_DOWN); // 下架
            }
            if (StringUtils.isNotEmpty(mallGoods.getOpenStartDate())) { // 上架未开售
                Date startTime = DateUtils.parse(mallGoods.getOpenStartDate(), "yyyy-MM-dd HH:mm");
                mallGoods.setOpenStartTime(startTime);
            }
        }

        String firstPic = goodsResourceBizService.getFirstPic(mallGoods.getPicList());
        mallGoods.setPic(firstPic);
        if (Strings.isNullOrEmpty(mallGoods.getId())) {
            mallGoods.setMemberId(memberId);
            mallGoods.setSalesNum(0L);
            mallGoods.setRealStock(mallGoods.getStock());
            mallGoodsService.insert(mallGoods);

            try {
                mallBrandBizService.updateGoodsNum("", mallGoods.getBrandId());
                goodsCategoryBizService.updateGoodsNum(true, mallGoods.getId(), mallGoods.getCategoryList());
            } catch (Exception e) {
                logger.error("处理品牌和分类的商品数异常", e);
            }
        } else {
            MallGoods dbGoods = mallGoodsService.get(mallGoods.getId());
            memberId = dbGoods.getMemberId();
        }

        // 保存分类和品牌的关系
        goodsCategoryBizService.saveCategoryBrand(mallGoods.getCategoryList(), mallGoods.getBrandId());
        // 保存分类和商品的关系
        goodsCategoryBizService.saveCategoryBiz(mallGoods.getId(), mallGoods.getCategoryList());
        // 保存资源（图片、视频）
        goodsResourceBizService.saveResourceBiz(mallGoods.getId(), mallGoods.getPicList(), mallGoods.getVideoList(), memberId);
        // 保存详情
        goodsDetailBizService.saveDetailBiz(mallGoods.getId(), goodsDetail);
        // 保存规格、产品
        productBizService.saveProductBiz(mallGoods, mallGoods.getProducts(), mallGoods.getSpecs());

        if (StringUtils.isNotEmpty(mallGoods.getId())) {
            MallGoods dbGoods = mallGoodsService.get(mallGoods.getId());
            Long salesNum = 0L;
            List<String> productIds = Lists.newArrayList();
            List<MallProduct> mallProductList = mallProductService.findByGoodsId(mallGoods.getId());
            for (MallProduct mallProduct : mallProductList) {
                productIds.add(mallProduct.getId());
                salesNum += mallProduct.getSalesNum();
            }
            String oldBrandId = dbGoods.getBrandId();
            MyBeanUtils.copyBeanNotNull2Bean(mallGoods, dbGoods);
            Long notPayCount = mallOrderDetailService.getNotPay(mallGoods.getId(), productIds);
            dbGoods.setRealStock(mallGoods.getStock() - notPayCount - salesNum);
            if (dbGoods.getRealStock() > 0 && dbGoods.getStatus().equals(MallGoods.STATUS_SELL_OUT)) {
                dbGoods.setStatus(MallGoods.STATUS_UP);
            } else if (dbGoods.getRealStock() == 0 && !dbGoods.getStatus().equals(MallGoods.STATUS_SELL_OUT)) {
                dbGoods.setStatus(MallGoods.STATUS_SELL_OUT);
            }
            mallGoodsService.update(dbGoods);

            try {
                mallBrandBizService.updateGoodsNum(oldBrandId, mallGoods.getBrandId());
                goodsCategoryBizService.updateGoodsNum(false, mallGoods.getId(), mallGoods.getCategoryList());
            } catch (Exception e) {
                logger.error("处理品牌和分类的商品数异常", e);
            }
        }


        try {
            String filePath = fileBizService.getUploadCIPath(memberId, "mallGoods");
            String content = shopUrl + "goods/" + mallGoods.getId();
            fileBizService.uploadCloudOut(mallGoods.getId(), filePath, content, memberId, false);
        } catch (Exception e) {
            logger.error("上传商品二维码异常", e);
        }

        return mallGoods.getId();
    }

    /**
     * 商品编辑
     *
     * @param goodsId 商品id
     * @return
     */
    public Map<String, Object> goodsView(String goodsId) {
        boolean hasSpec = false;
        Map<String, Object> modelResult = Maps.newHashMap();
        MallGoodsDetail mallGoodsDetail = goodsDetailBizService.castToHtml(goodsId);
        modelResult.put("goodsDetail", mallGoodsDetail);
        // 跑马灯
        List<MallGoodsResources> picList = mallGoodsResourcesService.findByGoodsId(goodsId, MallGoodsResources.TYPE_PIC);
        modelResult.put("picList", picList);
        // 视频
        List<MallGoodsResources> videoList = mallGoodsResourcesService.findByGoodsId(goodsId, MallGoodsResources.TYPE_VIDEO);
        if (videoList.size() > 0) {
            modelResult.put("video", videoList.get(0));
        }

        MallGoods mallGoods = mallGoodsService.get(goodsId);
        Map<String, Object> specResult = productBizService.getBusiness(mallGoods);
        if (specResult.size() > 0) {
            if (specResult.get("speModels") != null && ((ArrayList) specResult.get("speModels")).size() > 0) {
                hasSpec = true;
            }
            if (!hasSpec) {
                List<MallProduct> products = (ArrayList) specResult.get("products");
                if (products.size() > 0) {
                    specResult.put("product", products.get(0));
                }
            }
        }
        specResult.put("hasSpec", hasSpec);
        modelResult.put("results", JSONObject.toJSONString(specResult));
        List<MallCategory> categoryList = mallCategoryService.getGoodsCategory(goodsId);
//        List<String> categoryIds = LangUtils.transform(categoryList, input -> input.getId());
//        modelResult.put("categoryIds", categoryIds.toString().replaceAll("\\[", "").replaceAll("\\]", ""));
        modelResult.put("categoryList", categoryList);
        modelResult.put("mallGoods", mallGoods);
        modelResult.put("hasSpec", hasSpec);
        return modelResult;
    }

    /**
     * 复制商品
     *
     * @param oldGoodsId 旧的商品
     * @throws Exception
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void copyGoods(String oldGoodsId) {
        MallGoods mallGoods = mallGoodsService.get(oldGoodsId);
        mallGoods.setId(null);
        mallGoods.setCreateDate(null);
        mallGoods.setUpdateDate(null);
        String newGoodsId = mallGoodsService.insert(mallGoods);

        try {
            mallBrandBizService.updateGoodsNum("", mallGoods.getBrandId());
        } catch (Exception e) {
            logger.error("处理品牌的商品数异常", e);
        }

        // 详情
        goodsDetailBizService.copyDetail(oldGoodsId, newGoodsId);
        // 资源（图片/视频）
        goodsResourceBizService.copyResource(oldGoodsId, newGoodsId);
        // 分类
        goodsCategoryBizService.copyCategory(oldGoodsId, newGoodsId);
        // 产品
        productBizService.copyProduct(oldGoodsId, newGoodsId);

        try {
            String filePath = fileBizService.getUploadCIPath(mallGoods.getMemberId(), "mallGoods");
            String content = shopUrl + "goods/" + newGoodsId;
            fileBizService.uploadCloudOut(newGoodsId, filePath, content, mallGoods.getMemberId(), false);
        } catch (Exception e) {
            logger.error("上传商品二维码异常", e);
        }
    }

    /**
     * 删除商品
     *
     * @param goodsId 商品编号
     * @return
     */
    public boolean deleteGoods(String goodsId) {
        List<MallProduct> products = mallProductService.findByGoodsId(goodsId);
        for (MallProduct product : products) {
            // 购物车
            List<MallShoppingCart> shoppingCarts = mallShoppingCartService.findByProductId(product.getId());
            // 订单
            List<MallOrderDetail> orderDetails = mallOrderDetailService.findByProductId(product.getId());
            // 没有过订单记录或者购物车的
            if (orderDetails.size() != 0) {
                throw new BusinessException("已产生订单");
            }
            if (shoppingCarts.size() != 0) {
                throw new BusinessException("已被加入购物车中");
            }
        }
        Long favoriteCount = mallGoodsFavoriteService.findByGoodsId(goodsId);
        if (favoriteCount > 0) {
            throw new BusinessException("已被收藏");
        }
        Integer settingCount = mallStoreResourcesService.findByTargetId(goodsId);
        if (settingCount > 0) {
            throw new BusinessException("已配置到店铺首页");
        }
        return deleteGoodsBiz(goodsId);
    }

    /**
     * 商品下架
     *
     * @param goodsId 商品id
     * @return
     */
    public boolean downGoods(String goodsId) {
        boolean checkDelete = true;
        List<MallProduct> products = mallProductService.findByGoodsId(goodsId);
        for (MallProduct product : products) {
            // 待支付订单
            Long count = mallOrderDetailService.getNotPay(product.getId(), "");
            // 没有过订单记录或者购物车的
            if (count > 0) {
                checkDelete = false;
                break;
            }
        }
        if (!checkDelete) {
            return checkDelete;
        }
        return true;
    }

    /**
     * 获取商品id
     *
     * @param type     1：分类 2：商品
     * @param targetId 分类id或者商品id
     * @return
     */
    public List<String> getGoodsIds(Integer type, String targetId) {
        List<String> goodsIds = Lists.newArrayList();
        if (type == null || StringUtils.isEmpty(targetId)) {
            return goodsIds;
        }
        if (type == MallShowGoods.TYPE_GOODS) {
            goodsIds.add(targetId);
        } else if (type == MallShowGoods.TYPE_CATEGORY) {
            List<MallGoodsCategory> goodsCategories = mallGoodsCategoryService.findByCategoryId(targetId);
            goodsIds = LangUtils.transform(goodsCategories, new Function<MallGoodsCategory, String>() {
                @Override
                public String apply(MallGoodsCategory input) {
                    return input.getGoodsId();
                }
            });
        }
        return goodsIds;
    }

    public void reviseStock() {
        List<MallGoods> mallGoods = mallGoodsService.list(new MallGoods());
        for (MallGoods mg : mallGoods) {
            List<MallProduct> products = mallProductService.list(new MallProduct(mg.getId()));
            for (MallProduct product : products) {
                Long notPayCount = mallOrderDetailService.getNotPay(product.getId(), mg.getId());
                Long salesNumCount = mallOrderDetailService.getSalesNum(product.getId(), null);
                long realStock = product.getStock() - notPayCount - salesNumCount;
                if (product.getRealStock() != realStock) {
                    product.setRealStock(realStock);
                    mallProductService.update(product);
                }
            }
        }
    }

    /**
     * 删除商品
     *
     * @param goodsId 商品编号
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean deleteGoodsBiz(String goodsId) {
        boolean endResult = true;
        String memberId = null;
        try {
            if (StringUtils.isEmpty(goodsId)) {
                endResult = false;
                return endResult;
            }
            MallGoods mallGoods = mallGoodsService.get(goodsId);
            if (mallGoods == null) {
                endResult = false;
                return endResult;
            }
            memberId = mallGoods.getMemberId();

            // 删除详情
            goodsDetailBizService.deleteByGoods(goodsId);
            // 删除资源
            goodsResourceBizService.deleteByGoods(goodsId);
            // 删除分类
            goodsCategoryBizService.deleteByGoods(goodsId);
            // 删除产品、规格
            productBizService.deleteByGoods(goodsId);
            // 更新商品数
            mallBrandBizService.subGoodsNum(mallGoods.getBrandId());
            // 删除收藏
            mallGoodsFavoriteService.deleteByGoods(goodsId);
            // 删除首页资源
            mallStoreResourcesService.deleteByTargetId(goodsId);
            // 删除展示商品
            mallShowGoodsBizService.deleteShowGoodsBiz(goodsId);
            // 删除分销关系
            distributionBizService.deleteDistributionBiz(goodsId, null);
            // 删除商品
            mallGoodsService.delete(goodsId);
        } catch (Exception e) {
            endResult = false;
            logger.error("删除商品失败", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        } finally {
            if (endResult) {
                try {
                    String filePath = fileBizService.getUploadCIPath(memberId, "mallGoods");
                    String detailPath = CosBizService.getDeleteQrCodePath(filePath, goodsId);
                    cosBizService.deleteFile(detailPath);
                } catch (Exception e) {
                    logger.error("删除商品二维码失败", e);
                }
            }
        }
        return endResult;
    }
}
